home *** CD-ROM | disk | FTP | other *** search
- /* --------------------------------------------------------------------
- *
- * A christmas blanker inspired by xsnow
- *
- * initialization/cleanup code copied from the dragon module
- * (dragon module: (C)Alexander Kneer and Michael D. Bayne)
- *
- * -------------------------------------------------------------------- */
-
-
- #include <exec/memory.h>
- #include <math.h>
- #include <stdlib.h>
-
- #include "/includes.h"
-
- #define STAGES 2 /* Number of different shapes */
- #define BLANKDELAY 100 /* This many snowflakes are displayed before
- * we check if to continue blanking */
- #define COUNTLIMIT 6 /* max. number of moves in one direction */
- #define COUNTMIN 1 /* min. number of moves in one direction */
-
- /* random generation function macros */
- #define COUNTFUNC RangeRand(COUNTLIMIT-COUNTMIN)+COUNTMIN
- #define DXFUNC RangeRand(5)-2;
- #define DYFUNC RangeRand(2)+1;
-
- typedef enum { false, true } bool;
-
- bool BIGFLAKES;
- int NUMSNOW;
- bool COLLECT;
-
- int patx[10] = { -1,-1, 1, 1, 0 , -1, 1, 0, 0, 0 };
- int paty[10] = { -1, 1,-1, 1, 0 , 0, 0, 1,-1, 0 };
-
- int *collect;
-
- typedef struct
- { int x,y; /* The current coordinates */
- int dx,dy; /* Movement direction is (dx,dy) */
- int count; /* How long to keep direction dx */
- int stage; /* STAGES different shapes */
- } snowflake;
-
-
- Triplet *ColorTable = 0L;
-
-
- #define PR_FLAKE 0
- #define PR_BIG 2
- #define PR_COLLECT 4
- #define PR_MODE 6
-
- VOID Defaults( PrefObject *Prefs )
- {
- Prefs[PR_FLAKE].po_Level = 200;
- Prefs[PR_BIG].po_Level = 1;
- Prefs[PR_COLLECT].po_Level = 1;
- Prefs[PR_MODE].po_ModeID = getTopScreenMode();
- }
-
-
- /* Remove a single snowflake's image from the screen */
- __inline void undraw(snowflake *flake, struct RastPort *rp)
- {
- if (BIGFLAKES)
- {
- int *startx = patx + 5*(flake->stage);
- int *starty = paty + 5*(flake->stage);
- int i;
- SetAPen(rp,0);
- for (i=0; i<5; i++)
- { WritePixel(rp,flake->x+(*startx),flake->y+(*starty));
- startx++;
- starty++;
- }
- }
- else
- {
- SetAPen(rp,0);
- WritePixel(rp,flake->x,flake->y);
- }
- }
-
-
- /* Draw a single snowflake's image to the screen */
- __inline void draw(snowflake *flake, struct RastPort *rp)
- {
- if (BIGFLAKES)
- {
- int *startx = patx + 5*(flake->stage);
- int *starty = paty + 5*(flake->stage);
- int i;
- SetAPen(rp,1);
- for (i=0; i<5; i++)
- { WritePixel(rp,flake->x+(*startx),flake->y+(*starty));
- startx++;
- starty++;
- }
- }
- else
- { SetAPen(rp,1);
- WritePixel(rp,flake->x,flake->y);
- }
- }
-
-
- /* change the position of a snowflake. If it leaves [0..width]x[0..height],
- * generate a new one with coordinates (<random>,0) */
- __inline void update(snowflake *curr, int width, int height, struct RastPort *rp)
- { bool gen_new;
- int oldx = curr->x;
- if (curr->count > 0)
- { curr->y = curr->y + curr->dy;
- if (curr->y >= height-1)
- { gen_new = true;
- }
- else
- { curr->x = curr->x + curr->dx;
- if (curr->x < 1 || curr->x >= width-1)
- { gen_new = true;
- }
- else
- { gen_new = false;
- (curr->count)--;
- if (curr->count <= 0)
- { curr->dx = DXFUNC;
- curr->count = COUNTFUNC;
- }
- if (curr->stage)
- { curr->stage--;
- }
- else
- { curr->stage = STAGES-1;
- }
- }
- }
- }
-
- /* do we have to compute a new flake? */
- if (gen_new)
- { if (collect && curr->y > height-3)
- { collect[oldx]--;
- if (collect[oldx]<height-20)
- { collect[oldx]=height-20;
- }
-
- curr->x = oldx;
- curr->y = collect[oldx];
- draw(curr,rp);
- }
- curr->x = RangeRand(width-2)+1;
- curr->y = 1;
- curr->dx = DXFUNC;
- curr->dy = DYFUNC;
- curr->count = COUNTFUNC;
- curr->stage = RangeRand(STAGES);
- }
- }
-
-
-
-
- LONG snow(struct Screen *scr, SHORT width, SHORT height)
- {
- unsigned int i;
- LONG flg_end;
- snowflake *flake,*curr;
- int blankcount;
- struct RastPort *rp = &(scr->RastPort);
-
- /* initialize the snow array */
- flake = malloc(NUMSNOW*sizeof(snowflake));
- curr = flake;
- for (i=0; i<NUMSNOW; i++)
- { curr->x = RangeRand(width-2)+1;
- curr->y = RangeRand(height-2)+1;
- curr->dx = DXFUNC;
- curr->dy = DYFUNC;
- curr->count = COUNTFUNC;
- curr->stage = RangeRand(STAGES);
- curr++;
- }
-
- /* and the collect array */
- if (COLLECT)
- { collect = malloc(sizeof(int)*width);
- for (i=0; i<width; i++)
- { collect[i] = height-2;
- }
- collect[0] = 0;
- collect[width-1] = 0;
- }
- else
- { collect = NULL;
- }
-
- /* Update all snowflakes forever. Update includes removal from the screen,
- * computation of new position, drawing on the screen */
- blankcount = BLANKDELAY;
- while (1)
- { curr = flake;
- for (i=0; i<NUMSNOW; i++)
- { /* Remove curr's image */
- undraw(curr,rp);
- /* compute new position and appearance */
- update(curr,width,height,rp);
- /* and display it */
- draw(curr,rp);
- /* can we continue? */
- if (!blankcount)
- { blankcount = BLANKDELAY;
- flg_end = ContinueBlanking();
- ScreenToFront(scr);
- if (flg_end != OK)
- { free(flake);
- if (collect) free(collect);
- return flg_end;
- }
- }
- else
- { blankcount--;
- }
- curr++;
- }
- }
- return OK; /* just for the compiler */
- }
-
-
- LONG Blank( PrefObject *Prefs )
- {
- struct Screen *Scr;
- struct Window *Wnd;
- LONG RetVal;
-
- BIGFLAKES = Prefs[PR_BIG].po_Level;
- NUMSNOW = Prefs[PR_FLAKE].po_Level;
- COLLECT = Prefs[PR_COLLECT].po_Level;
-
- if( Scr = OpenScreenTags( NULL, SA_Depth, 1,
- SA_Quiet, TRUE, SA_DisplayID, Prefs[PR_MODE].po_ModeID,
- SA_Behind, TRUE, SA_Overscan, OSCAN_STANDARD,
- TAG_DONE ))
- {
- SetRGB4(&( Scr->ViewPort ), 0, 0, 0, 0 );
- ColorTable = RainbowPalette( Scr, 0L, 1L, 0L );
- SetRGB4(&( Scr->ViewPort ), 1, 15, 15, 15 );
- Wnd = BlankMousePointer( Scr );
-
- do
- RetVal = snow( Scr, Scr->Width, Scr->Height );
- while( RetVal == OK );
-
- UnblankMousePointer( Wnd );
- RainbowPalette( 0L, ColorTable, 1L, 0L );
- CloseScreen( Scr );
- }
- else
- RetVal = FAILED;
-
- return RetVal;
- }
-